package org.breathe.thread.pool.common.enums;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.breathe.thread.pool.common.exception.DtpException;
import org.breathe.thread.pool.common.queue.MemorySafeLinkedBlockingQueue;
import org.breathe.thread.pool.common.queue.VariableLinkedBlockingQueue;

import java.util.Arrays;
import java.util.concurrent.*;

/**
 * 阻塞队列枚举类型
 * @author: breathe
 * @createTime: 2025-04-09
 */
@Slf4j
@Getter
public enum QueueTypeEnum {
    /**
     * 阻塞队列类型
     */
    ARRAY_BLOCKING_QUEUE(1, "ArrayBlockingQueue", ((capacity, fair) -> new ArrayBlockingQueue<>(capacity))),
    LINKED_BLOCKING_QUEUE(2, "LinkedBlockingQueue", ((capacity, fair) -> new LinkedBlockingQueue<>(capacity))),
    PRIORITY_BLOCKING_QUEUE(3, "PriorityBlockingQueue", ((capacity, fair) -> new PriorityBlockingQueue<>(capacity))),
    DELAY_QUEUE(4, "DelayQueue", ((capacity, fair) -> new DelayQueue())),
    SYNCHRONOUS_QUEUE(5, "SynchronousQueue", ((capacity, fair) -> new SynchronousQueue<>(fair))),
    LINKED_TRANSFER_QUEUE(6, "LinkedTransferQueue", ((capacity, fair) -> new LinkedTransferQueue<>())),
    LINKED_BLOCKING_DEQUE(7, "LinkedBlockingDeque", ((capacity, fair) -> new LinkedBlockingDeque<>(capacity))),
    VARIABLE_LINKED_BLOCKING_QUEUE(8, "VariableLinkedBlockingQueue", ((capacity, fair) -> new VariableLinkedBlockingQueue<>(capacity))),
    MEMORY_SAFE_LINKED_BLOCKING_QUEUE(9, "MemorySafeLinkedBlockingQueue", ((capacity, fair) -> new MemorySafeLinkedBlockingQueue<>(capacity)))
    ;
    private final Integer code;
    private final String name;
    private final QueueCreator creator;
    private interface QueueCreator {
        BlockingQueue<Runnable> create(int capacity, boolean fair);
    }
    QueueTypeEnum(Integer code, String name, QueueCreator creator) {
        this.code = code;
        this.name = name;
        this.creator = creator;
    }
    public static BlockingQueue<Runnable> buildBlockingQueue(String name, int capacity, boolean fair) {
        return Arrays.stream(values())
                .filter(e -> e.name.equals(name))
                .findFirst()
                .map(e -> e.creator.create(capacity, fair))
                .orElseThrow(() -> {
                    log.error("can't find this blockingQueue {}", name);
                    return new DtpException("can't find this blockingQueue " + name);
                });
    }
}